﻿using Microsoft.AspNetCore.Mvc.ApplicationModels;
using Microsoft.AspNetCore.Mvc.ModelBinding;

namespace ModelBinder.Web.Infrastructures.ApplicationModelProviders;

internal sealed class CustomApiBehaviorApplicationModelProvider : IApplicationModelProvider
{
    public CustomApiBehaviorApplicationModelProvider(
        IModelMetadataProvider modelMetadataProvider,
        IServiceProvider serviceProvider)
    {
        ActionModelConventions = new List<IActionModelConvention>();

        var serviceProviderIsService = serviceProvider.GetService<IServiceProviderIsService>();
        var convention = serviceProviderIsService is null ?
            new CustomInferParameterBindingInfoConvention(modelMetadataProvider) :
            new CustomInferParameterBindingInfoConvention(modelMetadataProvider, serviceProviderIsService);
        ActionModelConventions.Add(convention);
    }

    /// <remarks>
    /// Order is set to execute after the <see cref="DefaultApplicationModelProvider"/> and allow any other user
    /// <see cref="IApplicationModelProvider"/> that configure routing to execute.
    /// </remarks>
    public int Order => -1000 + 100;

    public List<IActionModelConvention> ActionModelConventions { get; }

    public void OnProvidersExecuted(ApplicationModelProviderContext context)
    {
    }

    public void OnProvidersExecuting(ApplicationModelProviderContext context)
    {
        foreach (var controller in context.Result.Controllers)
        {
            foreach (var action in controller.Actions)
            {
                foreach (var convention in ActionModelConventions)
                {
                    convention.Apply(action);
                }
            }
        }
    }
}